[t:/]$ 지식_

spark의 mapPartitions

2018/03/13

... 써 놓고 보니 설명이 좀 애매함.

map은 각 줄을 받아와서 처리하고 새 줄을 리턴한다. mapPartitons는 파티션의 iter를 받아와서 처리하고 현재 포지션만 처리한 후 바로 리턴한다. 이 함수는 그 자리에서 완전한 루프를 돌지 않고 iter의 포지션이 변경될 때 수행하고 yield에서 리턴한다. 즉, 파티션 전체를 대상으로 하되, for 루프에서 한 줄 씩 그 때 그 때 받아와서 yield에서 바로 리턴한다. for 대신에 다른 키워드를 썼으면 좋았을 것을.

python에서 iter, yield (generator)를 이해하기 어렵다. python의 for문은 list나 iterator를 순회할 수 있는데, list만 순회한다고 생각할 때 꼬인다.

    for i in [1, 2, 3, 4]:
...

    for i in iter([1, 2, 3, 4]):

두 형식이 모두 가능하다. 여기에서는 1, 2, 3, 4가 모두 리스트에 들어있으므로 사실은 같다. 엄청 큰 파일이라면 어떨까. 100만 줄을 리스트에 다 때려넣고 할 수도 있겠지만 메모리를 많이 먹는다.

def map_f0(part):

    for line in part:
        l = line.strip().split('\001')
        uid = l[0]
        ds  = l[1]
        seg = l[2]
        f   = ('0' + '\t' + l[3]).split('\t')

        if ds in dss:
            yield (uid, ds, seg, f)

이 소스는 part의 전체를 불러오지 않는다. iter의 레퍼런스만 받아온다. for 순회에서는 레퍼런스만 증가시켜가면서 순회하고, 처리한 결과를 yield로 바로 던진다.

이 함수는 type으로 검사하면 함수다. a = map_f0()를 하면 a가 generator가 된다. a = map_f0 를 하면 a는 함수다. C의 함수포인터와 같다.

모아서 iter를 던져도 되지만 모으는 동안 시간과 메모리를 쓸 것 이다. generator의 효용을 누리지 못할 것 같은데 정확히는 살펴봐야겠다. 물론 리턴할 때 레퍼런스만 던질 테니까 그 점에 있어서는 유효한 측면도 있을 것 같다.

spark에서는 뭐가 유용할까?

map을 쓰면 줄 by 줄로 처리하니 반드시 리턴하는 줄이 있어야 한다. filter를 따로 써야 뭔가 걸를 수가 있따. mapPartitions를 쓰면 filter를 쓰지 않아도 된다. 위 소스가 바로 필터링 함수다.





공유하기













[t:/] is not "technology - root". dawnsea, rss